package com.web.all.common.util;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.DatatypeConverter;
import java.security.Key;
import java.util.Date;

/**
 * token工具类
 *
 * @author yangk
 */
@Component
@Slf4j
public class WebTokenUtil {

    private WebTokenUtil(){}

    /**
     * 设置默认日志缓存时间为7天
     */
    private static final int DEFAULT_LOG_TIME = 7;

    /**
     * 生成一个token值
     * @param dingUserId 用户id
     * @return toekn值
     */
    public static String getWebToken(String dingUserId) {

        // 生成签名密钥
        byte[] apiKeySecretBytes = DatatypeConverter.parseBase64Binary(WebTokenConfig.SALT);
        Key signingKey = new SecretKeySpec(apiKeySecretBytes, SignatureAlgorithm.HS256.getJcaName());
        // 添加构成JWT的参数,存储为json
        JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT").claim(WebTokenConfig.USER_KEY,dingUserId).setIssuer(WebTokenConfig.NAME)
                .signWith(SignatureAlgorithm.HS256, signingKey);
        // 添加Token过期时间
        long ttlMillis = 0;
        if(WebTokenConfig.EXPIRES_DAY > 0){
            ttlMillis = WebTokenConfig.EXPIRES_DAY;
        }else{
            ttlMillis = DEFAULT_LOG_TIME;
        }
        ttlMillis = ttlMillis * 24 * 60 * 60 * 1000;
        long nowMillis = System.currentTimeMillis();
        Date now = new Date(nowMillis);
        long expMillis = nowMillis + ttlMillis;
        Date exp = new Date(expMillis);
        builder.setExpiration(exp).setNotBefore(now);
        // 生成JWT
        return builder.compact();
    }

    /**
     * 获取用户ID
     * @param jsonWebToken toek值
     * @return 用户Id
     */
    public static String getUserIdByWebToken(String jsonWebToken) {
        try {
            Claims claims = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(WebTokenConfig.SALT))
                    .parseClaimsJws(jsonWebToken).getBody();
            Object obj =   claims.get(WebTokenConfig.USER_KEY);
            if(ObjectUtil.isNull(obj)){
                return  "-1";
            }else{
                return obj.toString();
            }
        } catch (Exception ex) {
            log.error("解析token值：获取用户ID" + ex);
        }
        return null;
    }

    /**
     * 获取webtoken的失效时间
     *
     * @param jsonWebToken
     * @return
     * @author yfl
     * @date 2017年7月10日 上午11:52:52
     */
    public static Long getWebTokenTime(String jsonWebToken) {
        try {
            Claims claims = Jwts.parser().setSigningKey(DatatypeConverter.parseBase64Binary(WebTokenConfig.SALT))
                    .parseClaimsJws(jsonWebToken).getBody();
            return claims.getExpiration().getTime();
        } catch (Exception ex) {
            log.error("解析token值：" + ex);
        }
        return null;
    }


    public static String getUserIdByRequest(HttpServletRequest request) {
        String jsonWebToken = request.getHeader(WebTokenConfig.TOKEN_HEADER_KEY);
        log.info("token log --> "+jsonWebToken);
        if(StrUtil.isEmpty(jsonWebToken)){
            return "0";
        }
        return getUserIdByWebToken(jsonWebToken);
    }
}
